package org.example.strategy;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.List;


/**
 * @author zhaokuii11@163.com
 * @create 2021-12-06 9:54
 * @Description
 */
public class Test1 {
    private SessionFactory sessionFactory;//会话工厂
    private Session session;//会话
    private Transaction transaction;//事务

    @Before //juint测试方法 之前执行
    public void init() {
        System.out.println("init");
        //1. 根据 Configuration创建 会话工厂
        sessionFactory = new Configuration().configure().buildSessionFactory();
        //2. 创建 会话
        session = sessionFactory.openSession();
        //3. 创建事务
        transaction = session.beginTransaction();
    }

    @Test
    public void testMany2OneStrategy() {
//        Order order = session.get(Order.class, 1);
//        System.out.println(order.getCustomer().getCustomerName());
        List<Order> list = session.createQuery("from org.example.strategy.Order o").list();
        list.forEach(System.out::println);
/*
* 1. lazy 取值 proxy 和 false分别代表对应的属性采用延迟检索和理解检索
* 2. fetch 取值为 join，表示使用迫切左外连接的方式初始化 n 关联 1的一端的属性
* ==》忽略 lazy属性
* 3. batch-size,该属性需要设置在 1的那一端的 class元素中。
* ==》<class name="Order" table="tab_order" batch-size="5">
* ==》作用：一次初始化1的这一段代理对象的个数
* */

    }

    @Test
    public void testSetFetch() {
        List<Customer> list = session.createQuery("from org.example.strategy.Customer").list();
        System.out.println(list.size());
        list.forEach(System.out::println);
        /*
         * set 集合的 fetch属性：确定初始化 orders集合的方式。
         * 1. 默认取值为 select，通过正常的方式来初始化 set元素。
         * 2. 可以取值为 subselect，通过子查询的方式来初始化所有的 set集合，子查询
         * ==》作为where子句的 in的条件出现，子查询所有1的一端的 id。
         * ==》此时 lazy有效，batch-size 失效
         * 3. 若取值为 join
         * 3.1 在加载 1的一端的对象时，使用迫切左外连接(使用左外连接进行查询，
         * ==》且把集合属性进行初始化)的方式检索n的一端的集合属性
         * 3.2 忽略 lazy属性
         * 3.3 hql 查询忽略 fetch=join的取值
         * */
    }

    @Test
    public void testBathcSize() {
        List<Customer> list = session.createQuery("from org.example.strategy.Customer").list();
        System.out.println(list.size());
        list.forEach(System.out::println);
        /*
         * set 元素的 batch-size属性；设定一次初始化 set集合的数量。
         *
         * */
    }

    @Test
    public void testOne2ManyLevelStrategy() {
        Customer customer = session.get(Customer.class, 1);
        System.out.println(customer.getCustomerName());
        Hibernate.initialize(customer.getOrders());//初始化
        /*
         * ===========set 的 lazy 属性==========
         * 1. 1-n 或 n-n 的集合属性默认使用懒加载检索策略
         * 2. 可以通过 set 的 lazy属性修改默认的检索策略,默认为true
         * ==》并不建议设置为 false
         * 3. lazy 还可以设置为 extra。增强的延迟检索。
         * ==》该取值会尽可以能的延迟集合初始化的时机。
         * */
    }

    @Test
    public void testClassLevelStrategy() {
        Customer load = session.load(Customer.class, 1);
        System.out.println(load.getClass());//代理对象

        System.out.println(load.getCustomerId());
        System.out.println(load.getCustomerName());
    }

    @After//juint测试方法 之后执行
    public void destroy() {
        //先开后关
        System.out.println("destroy");
        transaction.commit();
        session.close();
        sessionFactory.close();
    }
}
